步入 机器级程序视图,其中硬件的复杂性被抽象为一个结构化的 虚拟地址空间。在此视图中,内存并非变量的集合,而是一个巨大的、连续的8位块数组,称为 字节。对于具有 $w$ 位字长的机器,这些地址范围从 $0$ 到 $2^w - 1$,定义了程序可访问的边界。
1. 十六进制的力量
二进制是电路的语言,但 十六进制表示法 是程序员的语言。由于 $16 = 2^4$,一个十六进制数字(0–F)能完美映射到一个4位的半字节。这使得一个字节的值可以用恰好两个数字紧凑地表示(例如, 0xFF)。这种简写对于阅读 机器码 和 汇编代码至关重要,例如指令 4004dc: 48 03 47 28。
2. 精度与算术
当我们操作 整型数据类型时,会遇到 布尔环 和 补码 逻辑。我们必须应对 小端存储 存储方式、 整数溢出以及 单精度 浮点数中的 无穷大 ($+\infty$) 和 NaN 存在。理解这些位模式是掌握 任意大小算术 和健壮系统编程的第一步。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
Perform the following number conversions: 0x39A7 to binary, and binary 1101101001111101 to hexadecimal.
0x39A7 = 0011100110100111; Binary = 0xDA7D
0x39A7 = 1111001110100111; Binary = 0xDA7D
0x39A7 = 0011100110100111; Binary = 0xEA7D
0x39A7 = 0011100111100111; Binary = 0xDA8D
✅ Correct!
0x3=0011, 0x9=1001, 0xA=1010, 0x7=0111. For the second: 1101=D, 1010=A, 0111=7, 1101=D.❌ Incorrect
Each hex digit corresponds to a 4-bit nibble. Match 0x3 to 0011, 0x9 to 1001, etc.QUESTION 2
Suppose a=0x55 and b=0x46. What is the result of the bitwise operations 'a & b' and 'a ^ b' in hexadecimal?
a & b = 0x44; a ^ b = 0x11
a & b = 0x44; a ^ b = 0x13
a & b = 0x54; a ^ b = 0x13
a & b = 0x44; a | b = 0x55
✅ Correct!
0x55 (01010101) and 0x46 (01000110). AND results in 01000100 (0x44). XOR results in 00010011 (0x13).❌ Incorrect
Convert hex to binary, apply the bitwise operator bit-by-bit, and convert back to hex.QUESTION 3
In a 4-bit Two's-Complement system, what is the unsigned representation (T2U) of the value -1?
1
15
7
8
✅ Correct!
$T2U_w(x) = x + 2^w$ for $x < 0$. So $-1 + 16 = 15$.❌ Incorrect
A signed -1 in 4-bit binary is 1111, which represents 15 in unsigned.QUESTION 4
Which C expression is equivalent to (x == y) using only bit-level and logical operations?
!(x ^ y)
x & y
~(x | y)
!!(x ^ y)
✅ Correct!
x XOR y is 0 if and only if x equals y. The logical NOT (!) then turns 0 into 1 (True).❌ Incorrect
The XOR operator returns 0 for identical bits. How do we turn a 0 into a logical true?QUESTION 5
What is the result of '0x503c + 0x8' and '0x503c - 0x40' in hexadecimal?
0x5044 and 0x4FFC
0x5040 and 0x4F9C
0x5044 and 0x5000
0x5034 and 0x4FFC
✅ Correct!
0xC (12) + 0x8 (8) = 20 (0x14). So 0x503c + 8 = 0x5044. 0x3c (60) - 0x40 (64) = -4, borrow from next digit: 0x4FFC.❌ Incorrect
Remember that hex carries happen at 16, not 10. $C + 8 = 14_{16}$.Case Study: Numerical Representation and Logic Errors
Analysis of Integer vs. Floating-Point Bit Patterns
The integer 3,510,593 has hexadecimal representation 0x00359141. However, the single-precision floating-point number 3,510,593.0 is represented as 0x4A546504. You must analyze why these differ and how computer arithmetic handles these structures.
Q
1. Using the IEEE 754 formula $V = 2^E \times M$, explain why the floating-point hex 0x4A546504 corresponds to 3,510,593.0.
Solution:
The hex 0x4A546504 converts to binary: 0 [Sign] 10010100 [Exp] 10101000110010100000100 [Frac]. The exponent $e=148$, so $E = 148 - 127 = 21$. The significand $M = 1.frac$. Thus $V = 1.10101000110010100000100_2 \times 2^{21}$. Shifting the binary point 21 places right gives 1101010001100101000001.00_2, which is 3,510,593 decimal.
The hex 0x4A546504 converts to binary: 0 [Sign] 10010100 [Exp] 10101000110010100000100 [Frac]. The exponent $e=148$, so $E = 148 - 127 = 21$. The significand $M = 1.frac$. Thus $V = 1.10101000110010100000100_2 \times 2^{21}$. Shifting the binary point 21 places right gives 1101010001100101000001.00_2, which is 3,510,593 decimal.
Q
2. Identify the correlation between the bits of the integer (0x00359141) and the floating-point fraction bits.
Solution:
The integer 3,510,593 is $1101010001100101000001_2$. Notice that the significand of the float (ignoring the implicit leading 1) contains exactly these same bits shifted appropriately. The float bits are essentially a normalized version of the integer's bit pattern, shifted to fit the IEEE format.
The integer 3,510,593 is $1101010001100101000001_2$. Notice that the significand of the float (ignoring the implicit leading 1) contains exactly these same bits shifted appropriately. The float bits are essentially a normalized version of the integer's bit pattern, shifted to fit the IEEE format.
Q
3. Evaluate the C expression: 'x == $(int)(float)$ x' where x is a large 32-bit integer. Is it always true?
Solution:
False. A 32-bit 'int' can have up to 31 bits of precision. However, a single-precision 'float' only has 23 bits in its fraction (the significand). Therefore, large integers that require more than 23 bits of precision (like 3,510,593, which needs 22, but larger ones) will experience rounding errors when cast to float, losing their least significant bits.
False. A 32-bit 'int' can have up to 31 bits of precision. However, a single-precision 'float' only has 23 bits in its fraction (the significand). Therefore, large integers that require more than 23 bits of precision (like 3,510,593, which needs 22, but larger ones) will experience rounding errors when cast to float, losing their least significant bits.